/*
 * File:   engine_impl.h
 * Author: dolphinigle
 *
 * Created on December 1, 2011, 5:27 PM
 */

#ifndef ENGINE_IMPL_H
#define	ENGINE_IMPL_H

#include <string>
#include <algorithm>
#include <list>
using std::string;
using std::list;
using std::pair;

#include "engine.h"
#include "ipc_controller_interface.h"

// Main implementation of Engine.
// Bridges interface between the terminal's data and filesystem manager's data.
// Engine is also responsible for translating all paths into the correct
// absolute paths inside the virtual filesystem.
// Engine is also responsible for every commands that interacts with the real
// file system, for example, format, mountfs, unmount, cp, rm, ...

class EngineImpl : public Engine {
public:
  EngineImpl();
  virtual string Format(const Path& path, size_t size);
  virtual string MountFS(const Path& filesystem_location,
                         const Path& mount_point);
  virtual string Unmount(const Path& mount_point);
  virtual string Pwd();
  virtual string Ls();
  virtual string LsDirectory(const Path& directory);
  virtual string Cd(const Path& directory);
  virtual string Mkdir(const Path& path);
  virtual string Rm(const Path& path);
  virtual string Cp(const Path& origin, const Path& destination);
  virtual string Mv(const Path& origin, const Path& destination);
  virtual string Cat(const Path& filepath);
  virtual string Status();
  virtual string Exit();

  // Test only method
  string MountFSTest(const Path& filesystem_location, const Path& mount_point);

private:
  // Next id to be assigned for message queue.
  int next_msq_id_;

  string DoMountFS(const Path& filesystem_location, const Path& mount_point,
                   bool is_test);

  string LsRoot();

  // Current directory in virtual file system.
  string current_directory_;

  // List of directories and file systems controllers.
  list< pair<string, IPCControllerInterface*> > fs_;

  typedef list< pair<string, IPCControllerInterface*> >::iterator FsIt;

  // Makes a path absolute.
  Path MakeAbsolute(const Path& path);

  // Checks if the given path exists.
  bool IsExist(const Path& path);

  // Checks if the previous folder in the given path exists, if such folder
  // exists.
  // Only for virtual system paths.
  bool IsContainingFolderExists(const Path& path);

  // Retrieves the corresponding file system and strips the file system part
  // from the path.
  pair<string, IPCControllerInterface*> FindAndStrip(const Path& path);

  EngineImpl(const EngineImpl& orig) {
  }

  bool operator=(const EngineImpl& orig) {
  }
};

#endif	/* ENGINE_IMPL_H */

